#include "TestWrapper.h"
#include "AbstractWrapper.h"

#include "Parser.h"
#include "DesignExtractor.h"
#include "QueryPreprocessor.h"
#include "QueryOptimizer.h"
#include "QueryEvaulator.h"
#include "ResultFormatter.h"
#include <fstream>
#include <iostream>
#include <time.h>
using namespace std;

// implementation code of WrapperFactory - do NOT modify the next 5 lines
AbstractWrapper* WrapperFactory::wrapper = 0;
AbstractWrapper* WrapperFactory::createWrapper() {
  if (wrapper == 0) wrapper = new TestWrapper;
  return wrapper;
}
// Do not modify the following line
volatile bool TestWrapper::GlobalStop = false;

// a default constructor
TestWrapper::TestWrapper() {
  // create any objects here as instance variables of this class
  // as well as any initialization required for your spa program
}

// method for parsing the SIMPLE source
void TestWrapper::parse(std::string filename) {
	// call your parser to do the parsing
  // ...rest of your code...
	Parse(filename);
	Extract();
}

// method to evaluating a query
void TestWrapper::evaluate(std::string query, std::list<std::string>& results){
	string test_query = query;
	remove(test_query.begin(),test_query.end(),' ');
	remove(test_query.begin(),test_query.end(),'\n');
	remove(test_query.begin(),test_query.end(),'\t');
	remove(test_query.begin(),test_query.end(),'\0');
	
	if(test_query.size() == 1) return;
// call your evaluator to evaluate the query here
  // ...code to evaluate query...
	GenerateQueryTree(query,false);
	OptimizeQuery();
	//ErrorLocker::reset_b_query_error();
	//ErrorLocker::reset_s_error_message();
	ResultTable* p_result_table = NULL;
	//time_t time_start = time(NULL);
	bool b_flag = false;
	if( QueryTree::get_p_query_matrix()->size() * 2 > GetNumCPUs() )
	{	
		b_flag = QueryEvaluation(&p_result_table);
		cout << "multi-thread evaluation" << endl;
	}
	else
	{
		b_flag = BQE(&p_result_table);
		cout << "single thread evaluation" << endl;
	}
	//time_t time_end = time(NULL);
	//cout << "TIME USED: " << difftime(time_end,time_start) << endl;
  // store the answers to the query in the results list (it is initially empty)
  // each result must be a string.
	// case of select BOOLEAN
	if( p_result_table == NULL )
	{
		if( b_flag )
			results.push_back("true");
		else
			results.push_back("false");
	}
	// case of select non BOOLEAN
	else if( b_flag )
	{
			Format(p_result_table,results);
	}

	// Clean up
	optimize_stop = false;
	QueryVarTable::ClearQueryVarTable();
	QueryTree::ClearQueryTree();
}
